package kz.kstu.scantest.business.entity.data;

import kz.kstu.scantest.business.entity.CommonEntityConstant;
import kz.kstu.scantest.business.entity.Identifiable;
import kz.kstu.scantest.business.entity.guide.School;

import javax.persistence.*;
import java.util.*;

/**
 * @author Filipp_Stankevich
 *         created: 08.09.11 17:03
 */

@NamedQueries({
        @NamedQuery(name = CommonEntityConstant.FIND_SCAN_DATES,
                query = "select distinct f.createDate from FormData f order by f.createDate"),
        @NamedQuery(name = CommonEntityConstant.FIND_FORM_DATA_BY_CREATE_DATE_AND_SCHOOL,
                query = "select f from FormData f where f.createDate = :createDate and f.school = :school"),
        @NamedQuery(name = CommonEntityConstant.FIND_FORM_DATA_WITHOUT_SCHOOL_BY_CREATE_DATE,
                query = "select f from FormData f where f.createDate = :createDate and f.school is null"),
        @NamedQuery(name = CommonEntityConstant.FIND_FORM_DATA_WITH_ERRORS_BY_DATE_AND_SCHOOL,
                query = "select f from FormData f inner join f.formDataErrors fde where f.createDate = :createDate and f.school = :school"),
        @NamedQuery(name = CommonEntityConstant.FIND_FORM_DATA_WITH_ERRORS_BY_DATE_WITHOUT_SCHOOL,
                query = "select f from FormData f inner join f.formDataErrors fde where f.createDate = :createDate and f.school is null")
})

@Entity
@Table(name = "FORM_DATA")
public class FormData implements Identifiable {

    public static final String SURNAME_PROPERTY = "surname";

    public static final String VARIANT_PROPERTY = "variant";

    private Long id;
    private String variant;
    private String surname;
    private String initials;
    private String classLetter;
    private School school;
    private Date createDate;
    private Date processDate;
    private Set<FormDataError> formDataErrors;
    private List<SubjectData> subjects;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    @Override
    public Long getId() {
        return id;
    }

    @Override
    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "VARIANT")
    public String getVariant() {
        return variant;
    }

    public void setVariant(String variant) {
        this.variant = variant;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "PROCESS_DATE")
    public Date getProcessDate() {
        return processDate;
    }

    public void setProcessDate(Date processDate) {
        this.processDate = processDate;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "CREATE_DATE")
    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @ManyToOne
    @JoinColumn(name = "SCHOOL_ID", referencedColumnName = "ID")
    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    @Column(name = "CLASS_LETTER")
    public String getClassLetter() {
        return classLetter;
    }

    public void setClassLetter(String classLetter) {
        this.classLetter = classLetter;
    }

    @Column(name = "INITIALS")
    public String getInitials() {
        return initials;
    }

    public void setInitials(String initials) {
        this.initials = initials;
    }

    @Column(name = "SURNAME")
    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    @OneToMany(mappedBy = "formData", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    public Set<FormDataError> getFormDataErrors() {
        return formDataErrors;
    }

    public void setFormDataErrors(Set<FormDataError> formDataErrors) {
        this.formDataErrors = formDataErrors;
    }

    @OrderBy(value = "fieldName")
    @OneToMany(mappedBy = "formData", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    public List<SubjectData> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<SubjectData> subjects) {
        this.subjects = subjects;
    }

    public void addFormDataError(FormDataError formDataError) {
        if (formDataErrors == null) {
            formDataErrors = new HashSet<FormDataError>();
        }
        formDataError.setFormData(this);
        formDataErrors.add(formDataError);
    }


    public void addSubjectData(SubjectData subjectData) {
        if (subjects == null) {
            subjects = new ArrayList<SubjectData>();
        }
        subjects.add(subjectData);
    }

    @Transient
    public String getErrorMessage() {
        StringBuilder errorMessages = new StringBuilder();
        Set<FormDataError> errors = getFormDataErrors();
        if (errors != null) {
            for (FormDataError formDataError : errors) {
                errorMessages.append(formDataError.getDescription());
                errorMessages.append(";");
                errorMessages.append(" ");
            }
        }
        return errorMessages.toString();
    }
}
